package com.qf.service.impl;

import com.qf.api.CacheFeign;
import com.qf.constant.CacheConstants;
import com.qf.model.StandardSubmit;
import com.qf.service.FilterChainService;
import com.qf.service.StrategyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Map;

/**
 * @Author ztf
 * @Date 20:08 2021/11/24
 **/
@Service
@Slf4j
public class FilterChainServiceImpl implements FilterChainService {

    /**
     * key时策略实现类中的关键字
     * value时对应实现类的对像
     */
    @Autowired
    private Map<String, StrategyService> strategyServiceMap;

    @Autowired
    private CacheFeign cacheFeign;

    /**
     * 责任链管理方法
     * 管理执行策略的前后执行顺序，和是否执行
     *
     * @param standardSubmit
     */
    @Override
    public void executeFilter(StandardSubmit standardSubmit) throws IOException {

        //1.调用cache 模状获取redis中过滤器的执行顺序
        //例如:"black,router,fee,phase,limit,dirtyWord"
        Map<String,String> client = cacheFeign.hMGet(CacheConstants.CACHE_PREFIX_CLIENT + standardSubmit.getClientID());
        if (client == null){
            log.info("【策略模块 - 策略管理】，client对象为空：client={}",client);
            return;
        }

        //2.根据逗号分割,获取过滤器执行顺序数组
        String filters = client.get("filters");
        if (StringUtils.isEmpty(filters)){
            log.info("【策略模块 - 策略管理】，需要执行的策略为空：filters={}",filters);
            return;
        }
        String[] filterArray = filters.split(",");
        //3.遮历过滤器执行顺序数组
        for (String filterStr : filterArray) {
            //4.获取执行的过滤期实现类对象,FilterChainService chain=filterMap.get("black")
            StrategyService strategyService = strategyServiceMap.get(filterStr);
            //5.执行具体策略业务方法,chain.strategy(StandardSubmit submit);
            boolean flag = strategyService.execute(standardSubmit);
            //6.判断执行结果,如果返回为false停止执行,返回为true继续执行
            if (!flag){
                log.info("【策略模块 - 策略管理】，执行策略失败：策略名={}",filterStr);
                break;
            }
        }



    }
}
